package org.ala.tiktools.tools;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 动态加载类
 *
 * @author ala
 * @date 2025-02-27 15:58
 */
public class DynamicClassLoader extends ClassLoader {


    public static DynamicClassLoader instance;
    static {
        instance = new DynamicClassLoader();
    }


    /**
     *  类名与二进制对应关系
     */
    protected Map<String, ClassVersion> mapper = new ConcurrentHashMap<>();


    /**
     * 通过二进制加载class
     */
    public Class<?> loadClass(String name, byte[] bytes) {
        ClassVersion cv = mapper.get(name);
        if (cv == null || !cv.equalsBytes(bytes)) {
            synchronized (name.intern()) {
                cv = mapper.get(name);
                if (cv == null || !cv.equalsBytes(bytes)) {
                    defineClass(name, bytes, 0, bytes.length);
                }
            }
        }
        return null;
    }


    public Class<?> load(String name, byte[] bytes) {
        return defineClass(name, bytes, 0, bytes.length);
    }


    /**
     *  类名二进制版本数据
     */
    protected static class ClassVersion {
        String name;
        String className;
        Class<?> clazz;
        byte[] bytes;
        int version;
        public ClassVersion(String name, Class<?> clazz, byte[] bytes, int version) {
            this.name = name;
            this.clazz = clazz;
            this.bytes = bytes;
            this.version = version;
            this.className = String.format("%s_V%d", name, version);
        }
        /**
         *  比较二进制是否全等
         */
        public boolean equalsBytes(byte[] bytes) {
            if (this.bytes.length != bytes.length) {return false;}
            //  逐位比较
            for (int i = 0; i < bytes.length; i++) {
                if (this.bytes[i] != bytes[i]) {return false;}
            }
            return true;
        }
    }
}
